package com.uam.core.business;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mapbox.turf.TurfConstants;
import com.mapbox.turf.TurfMeasurement;
import com.uam.core.entity.PointInfoData;
import com.uam.core.entity.model.AircraftModel;
import com.uam.core.entity.model.TaskModel;
import com.uam.core.entity.uitls.SpatialUtil;
import com.uam.core.lk.utils.GeoTools;
import com.uam.core.tool.DateUtils;
import com.uam.core.lk.utils.fencebuffer.BufferBase;
import com.uam.core.lk.utils.fencebuffer.LineBufferImpl;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.operation.buffer.BufferOp;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author Administrator
 */
public class ParentBusiness {
    private int distance=200;

    LineBufferImpl lineBuffer=new LineBufferImpl();


    /**
     * 计算缓缓冲区域
     * @param aircraft
     * @param track
     * @return
     */
    public LineString routeAff(AircraftModel aircraft, JSONObject track){
        JSONArray trackCoordinates = track.getJSONArray("coordinates");
        int pointSize=trackCoordinates.size();
        //前两个点 和最后两个不进行计算
        List<Coordinate> coordinates=new ArrayList<>(pointSize);
        for(int i=1;i<pointSize-1;i++){
            JSONArray jsonArray= trackCoordinates.getJSONArray(i);
            coordinates.add(new Coordinate(jsonArray.getDouble(0),jsonArray.getDouble(1)));
        }
        LineString polygon= BufferBase.geometryFactory.createLineString(coordinates.toArray(new Coordinate[0]));
//        return lineBuffer(coordinates.toArray(new Coordinate[0]),aircraft.getSafeDistance());
        return polygon;
    }

    public Polygon lineBuffer(Coordinate[] coordinates,double buffer){
        LineString polygon= BufferBase.geometryFactory.createLineString(coordinates);
        return (Polygon) lineBuffer.getBuff(polygon, BufferOp.CAP_ROUND, buffer);
    }

    /**
     * 计算每个轨迹点飞行的时间戳
     * @param aircraft
     * @param track
     * @return
     */
    public JSONArray pointsTime(AircraftModel aircraft, JSONObject track, TaskModel taskModel){
        JSONArray trackCoordinates = track.getJSONArray("coordinates");
        int row=trackCoordinates.size();
        JSONArray jsonArrayNew=new JSONArray(row);
        //补点操作
        for(int i=0;i<row-1;i++){
            JSONArray jsonArray0=trackCoordinates.getJSONArray(i);
            JSONArray jsonArray1=trackCoordinates.getJSONArray(i+1);
            com.mapbox.geojson.Point currPoint = com.mapbox.geojson.Point.fromLngLat(jsonArray0.getDoubleValue(0), jsonArray0.getDoubleValue(1));
            com.mapbox.geojson.Point nextPoint = com.mapbox.geojson.Point.fromLngLat(jsonArray1.getDoubleValue(0), jsonArray1.getDoubleValue(1));
            jsonArrayNew.add(jsonArray0);
            double angle = TurfMeasurement.bearing(currPoint,nextPoint);
            double tmpDistance = SpatialUtil.computeDistance(currPoint.longitude(), currPoint.latitude(), nextPoint.longitude(), nextPoint.latitude());
            if(tmpDistance>distance){
               int num=(int)  tmpDistance/distance;
                com.mapbox.geojson.Point currPointNew = currPoint;
               for(int j=0;j<num;j++){
                   com.mapbox.geojson.Point  timePointNow=TurfMeasurement.destination(currPointNew, distance, angle, TurfConstants.UNIT_METERS);
                   JSONArray jsonArrayTemp=new JSONArray();
                   jsonArrayTemp.add(timePointNow.longitude());
                   jsonArrayTemp.add(timePointNow.latitude());
                   jsonArrayTemp.add(0);
                   jsonArrayNew.add(jsonArrayTemp);
                   currPointNew=timePointNow;
               }
            }

        }
        jsonArrayNew.add(trackCoordinates.get(row-1));
        getHistoryTime(jsonArrayNew,aircraft.getSpeed(),taskModel,0,true);
        return jsonArrayNew;
    }


    /**
     *
     * @param points 轨迹点数量
     * @param avgSpeed 平均速度 米/秒
     * @param isSolveData 是否需要添加冲突id数组
     * @return
     */
    public void getHistoryTime(JSONArray points, double avgSpeed,TaskModel taskModel,int index,boolean isSolveData)  {
        if(points == null || points.size()==0){
            return ;
        }
        JSONArray lonLat01=points.getJSONArray(index);
        //第一个点
        Date newTime=new Date(taskModel.getStartTime().getTime());

        if(isSolveData){
            lonLat01.add(3,new JSONArray());
        }
        setOrUpdate(lonLat01,newTime);

        int row=points.size();
        for(int i=index+1;i<row;i++){
            JSONArray upList=points.getJSONArray(i-1);
            JSONArray newList=points.getJSONArray(i);
            double lon1=upList.getDoubleValue(0);
            double lat1=upList.getDoubleValue(1);
            double lon2=newList.getDoubleValue(0);
            double lat2=newList.getDoubleValue(1);
            double dist=  SpatialUtil.computeDistance(lon1, lat1,lon2, lat2);
            double timeTemp=  new BigDecimal(dist/avgSpeed).setScale(3,BigDecimal.ROUND_HALF_UP).doubleValue();
            if(isSolveData){
                newList.add(new JSONArray());
            }

            if(newList.size() == 3){
                newList.add(new JSONArray());
            }

            setOrUpdate(newList,newTime);
            newTime =  DateUtils.getAddTime(newTime,(int)timeTemp);
        }
    }

    public void setOrUpdate(JSONArray newList,Date date){
        if(newList.size() == 5){
            newList.set(4,date);
            return;
        }
        newList.add(date);
    }
    public Date getPointTime(Date startTime,Coordinate p0,Coordinate p1,double avgSpeed){
        double dist=  new BigDecimal(GeoTools.distance(p0,p1)*100000).setScale(3,BigDecimal.ROUND_HALF_UP).longValue();
        double timeTemp=  new BigDecimal(dist/avgSpeed).setScale(3,BigDecimal.ROUND_HALF_UP).doubleValue();
        return DateUtils.getAddTime(startTime,(int)timeTemp);
    }

    public LineString jsonArrayNew( JSONArray jsonArrayLin) {
        Coordinate[] coordinatesLine = new Coordinate[jsonArrayLin.size()];
        for (int i = 0; i < jsonArrayLin.size(); i++) {
            coordinatesLine[i] = new Coordinate(jsonArrayLin.getJSONArray(i).getDouble(0), jsonArrayLin.getJSONArray(i).getDouble(1));
        }
        return BufferBase.geometryFactory.createLineString(coordinatesLine);
    }

    public LineString dataInfoToLineString(List<PointInfoData> dataLineList) {
        Coordinate[] coordinatesLine = new Coordinate[dataLineList.size()];
        for (int i = 0; i < dataLineList.size(); i++) {
            PointInfoData data = dataLineList.get(i);
            coordinatesLine[i] = new Coordinate(data.getLon(), data.getLat());
        }
        return BufferBase.geometryFactory.createLineString(coordinatesLine);
    }

//    /**
//     *
//     * @param points 轨迹点数量
//     * @param avgSpeed 平均速度 米/秒
//     * @return
//     */
//    public void getHistoryTimeNew(JSONArray points, double avgSpeed,TaskModel taskModel,int index)  {
//        if(points == null || points.size()==0){
//            return ;
//        }
//        JSONArray lonLat01=points.getJSONArray(index);
//        //第一个点
//        Date newTime=new Date(taskModel.getStartTime().getTime());
//        lonLat01.add(newTime);
//
//        int row=points.size();
//        long time=0;
//        for(int i=index;i<row;i++){
//            JSONArray upList=points.getJSONArray(i-1);
//            JSONArray newList=points.getJSONArray(i);
//            double lon1=upList.getDoubleValue(0);
//            double lat1=upList.getDoubleValue(1);
//            double lon2=newList.getDoubleValue(0);
//            double lat2=newList.getDoubleValue(1);
//            double dist=  new BigDecimal(GeoTools.distance(new Coordinate(lon1,lat1),new Coordinate(lon2,lat2))*100000).setScale(3,BigDecimal.ROUND_HALF_UP).longValue();
//            double timeTemp=  new BigDecimal(dist/avgSpeed).setScale(3,BigDecimal.ROUND_HALF_UP).doubleValue();
//            time=(long)(timeTemp*1000)+time;
//            newList.add((newTime));
//            newTime =  DateUtils.getAddTime(newTime,(int)timeTemp);
//        }

}
